<html>
  <head></head>
  <body>
    <p>实现一个Promise方法</p>
    <p>1、then 方法中的回调需要异步执行，利用setTimeout 异步执行 回调函数</p>
    <p>2、Promise 链式调用，then 方法中再返回一个Promise对象</p>
    <script>
      // MyPromise构造函数
      function MyPromise(callback) {
        this.status = 'pending' // 存储promise 的状态
        this.value = '' // 存储promise 的值 【resolve 和reject 的参数】
        this._resolveCallback = null // 存储then 方法中注册的第一个回调函数
        this._rejectCallback = null // 存储then 方法中注册的第二个回调函数

        // 必须用ES6 箭头函数
        // 将Promise 的状态从pending 更改为fulfilled，并且以value 为参数异步调用then 方法中注册的第一个回调
        const resolve = val => {
          setTimeout(() => {
            this.status = 'fulfilled'
            this.value = val
            this._resolveCallback && this._resolveCallback()
          }, 0)
        }

        // 将Promise 的状态从pending 更改为rejected，并且以value 为参数异步调用then 方法中注册的第二个回调
        const reject = val => {
          setTimeout(() => {
            this.status = 'rejected'
            this.value = val
            this._rejectCallback && this._rejectCallback()
          }, 0)
        }

        callback(resolve, reject)
      }

      // then方法
      MyPromise.prototype.then = function (resolveCallback, rejectCallback) {
        // 链式调用，返回一个Promise对象
        return new MyPromise((resolve, reject) => {
          if (this.status === 'pending') {
            this._resolveCallback = () => {
              try {
                const res = resolveCallback(this.value)
                resolve(res)
              } catch (err) {
                reject(err)
              }
            }
            this._rejectCallback = () => {
              try {
                const res = rejectCallback(this.value)
                resolve(res)
              } catch (err) {
                reject(err)
              }
            }
          }
        })
      }

      const p_2 = new MyPromise((resolve, reject) => {
        if (true) resolve('成功')
        else reject('失败')
      })
      p_2
        .then(
          val => {
            console.log(a);
            console.log('p_2_val', val)
            return '链式调用_1_then'
          },
          val => {
            console.log('p_1_val', val)
            return '链式调用_1_catch'
          },
        )
        .then(val => {
          console.log('p_2_val', val)
          return '链式调用_2_then'
        },)
        // .then(val => {
        //   console.log('p_2_val_then', val)
        // })
    </script>
  </body>
</html>
